import asyncio
import json
import time
import websockets

active_connections = {}
socket_status = {}


# 定义 WebSocket 处理程序
async def handler(websocket):
    global active_connections, socket_status
    active_connections[str(id(websocket))] = websocket
    socket_status[str(id(websocket))] = 'idle'
    print(f"客户端已连接,连接编码为:{id(websocket)}")
    await websocket.send(json.dumps({"type": "init", "data": id(websocket)}))
    try:
        async for message in websocket:
            print(f"收到{id(websocket)},消息: {message}")
            result = json.loads(message)
            if result.get('type') == 'connect':
                socket = active_connections.get(result.get('data'))
                if socket:
                    if str(id(socket)) == str(id(websocket)):
                        await websocket.send(json.dumps({"type": "tips", "data": "不能对自己发起"}, ensure_ascii=False))
                        continue
                    if socket_status.get(str(id(socket))) != 'idle':
                        await websocket.send(json.dumps({"type": "tips", "data": "对方繁忙中"}, ensure_ascii=False))
                        continue
                    socket_status[str(id(websocket))] = 'wait'
                    socket_status[str(id(socket))] = 'wait'
                    second = 10
                    while second >= 0 and socket_status[str(id(websocket))] == 'wait' and socket_status[
                        str(id(socket))] == 'wait':
                        await websocket.send(
                            json.dumps({"type": "tips", "data": "等待对方接受中,倒计时:" + str(second)}, ensure_ascii=False))
                        await socket.send(
                            json.dumps({"type": "pk", "data": {"id": str(id(websocket)), "second": second}},
                                       ensure_ascii=False))
                        second = second-1
                        await asyncio.sleep(1)
                    if socket_status[str(id(websocket))] == 'wait':
                        await websocket.send(
                            json.dumps({"type": "status", "data": "idle"},
                                       ensure_ascii=False))
                        socket_status[str(id(websocket))] = 'idle'
                    if socket_status[str(id(socket))] == 'wait':
                        await socket.send(
                            json.dumps({"type": "status", "data": "idle"},
                                       ensure_ascii=False))
                        socket_status[str(id(socket))] = 'idle'
                else:
                    await websocket.send(json.dumps({"type": "tips", "data": "账号不存在"}, ensure_ascii=False))
            elif result.get('type') == 'accept':
                socket = active_connections.get(result.get('data').get('id'))
                if socket_status[str(id(websocket))] == 'wait' and socket_status[str(id(socket))] == 'wait':
                    socket_status[str(id(websocket))] = 'prepare'
                    socket_status[str(id(socket))] = 'prepare'
                    await socket.send(
                        json.dumps({"type": "status", "data": 'prepare'}, ensure_ascii=False))
                    await websocket.send(
                        json.dumps({"type": "status", "data": 'prepare'}, ensure_ascii=False))
            elif result.get('type') == 'reject':
                socket = active_connections.get(result.get('data').get('id'))
                if socket_status[str(id(websocket))] == 'wait' and socket_status[str(id(socket))] == 'wait':
                    socket_status[str(id(websocket))] = 'idle'
                    socket_status[str(id(socket))] = 'idle'
                    await websocket.send(
                        json.dumps({"type": "status", "data": "idle"},
                                   ensure_ascii=False))
                    await socket.send(
                        json.dumps({"type": "status", "data": "idle"},
                                   ensure_ascii=False))
                    await socket.send(
                        json.dumps({"type": "tips", "data": "对方拒绝了你的PK请求"},
                                   ensure_ascii=False))
            elif result.get('type') == 'data':
                socket = active_connections.get(result.get('data').get('id'))
                if socket:
                    await socket.send(
                        json.dumps({"type": "data", "data": {"snake":result.get('data').get('snake'),"food":result.get('data').get('food')}}, ensure_ascii=False))
            elif result.get('type') == 'ready':
                socket = active_connections.get(result.get('data').get('id'))
                if socket_status[str(id(websocket))] == 'prepare':
                    socket_status[str(id(websocket))] = 'ready'
                    await socket.send(
                        json.dumps({"type": "data", "data": {"snake":result.get('data').get('snake'),"food":result.get('data').get('food')}}, ensure_ascii=False))
                if socket_status[str(id(websocket))] == 'ready' and socket_status[str(id(socket))] == 'ready':
                    socket_status[str(id(socket))] = 'busy'
                    socket_status[str(id(websocket))] = 'busy'
                    await socket.send(json.dumps({"type": "status", "data": "busy"},
                                                 ensure_ascii=False))
                    await websocket.send(json.dumps({"type": "status", "data": "busy"},
                                                 ensure_ascii=False))
                    for i in range(3, 0, -1):
                        await websocket.send(json.dumps({"type": "ready", "data": i}, ensure_ascii=False))
                        await socket.send(json.dumps({"type": "ready", "data": i}, ensure_ascii=False))
                        await asyncio.sleep(1)
                    await websocket.send(json.dumps({"type": "status", "data": "go"}, ensure_ascii=False))
                    await socket.send(json.dumps({"type": "status", "data": "go"}, ensure_ascii=False))
            elif result.get('type') == 'over':
                socket = active_connections.get(result.get('data').get('id'))
                socket_status[str(id(websocket))] = 'prepare'
                await socket.send(json.dumps({"type": "over", "data": result.get('data').get('score')},
                                             ensure_ascii=False))
            elif result.get('type') == 'exit':
                socket = active_connections.get(result.get('data').get('id'))
                socket_status[str(id(websocket))] = 'idle'
                socket_status[str(id(socket))] = 'idle'
                await socket.send(json.dumps({"type": "status", "data": "exit"},
                                             ensure_ascii=False))

    except websockets.exceptions.ConnectionClosed as e:
        print(f"连接关闭: {e}")
    finally:
        print(f"{id(websocket)},断开连接")
        if id(websocket) in active_connections:
            del active_connections[id(websocket)]
            print(f"Ensuring connection {id(websocket)} is removed")


# 主函数
async def main():
    # 启动 WebSocket 服务器，监听 localhost 上的 8765 端口
    async with websockets.serve(handler, "0.0.0.0", 8765):
        print("WebSocket 服务器正在运行...")
        # 等待直到服务器被手动停止（这里使用 asyncio.Future() 作为占位符）
        await asyncio.Future()  # 这将永远不会完成，除非被取消


# 运行主函数
if __name__ == "__main__":
    asyncio.run(main())
